﻿using Company.Communication.Serial;
using Company.Logger.Logs;
using Company.Share.Prism;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace Company.Main.ViewModels
{
    public class SerialPortComponentViewModel : BindableBase
    {
        public IRegionManager RegionManager { get; }
        public ISerialCommunication SerialCommunication { get;private set; }
        public ObservableCollection<string> PortNames { get; private set; }
        public ObservableCollection<int> BaudRates { get;private set; }
        public ObservableCollection<Log> LogCollection { get;private set; }
        public DelegateCommand SerialPortConnectionCommand { get;}
        public DelegateCommand<object> SelectPortCommand { get;}
        public DelegateCommand<object> SelectBaudRateCommand { get;}
        public DelegateCommand<object> SendDataCommand { get;}
        public DelegateCommand BackToPreviousViewCommand { get; }
        private bool _IsSerialPortConnected;

        public bool IsSerialPortConnected
        {
            get { return _IsSerialPortConnected; }
            set { _IsSerialPortConnected = value; RaisePropertyChanged(); }
        }

        public SerialPortComponentViewModel(ISerialCommunication serialCommunication, 
                                            IRegionManager regionManager)
        {
            RegionManager = regionManager;
            SerialCommunication = serialCommunication;
            LogCollection = new ObservableCollection<Log>();
            SerialPortConnectionCommand = new DelegateCommand(SerialPortConnection);
            SelectPortCommand = new DelegateCommand<object>(SelectPort);
            SelectBaudRateCommand = new DelegateCommand<object>(SelectBaudRate);
            SendDataCommand = new DelegateCommand<object>(SendData);
            BackToPreviousViewCommand = new DelegateCommand(BackToPreviousView);
            // 初始化
            Initialize();
            // 事件订阅
            SerialCommunication.DataReceivedEvent += (sData) => 
            {
                // ObservableCollection类型不支持事件线程调度
                Application.Current.Dispatcher.Invoke(() => 
                {
                    if (LogCollection.Count > 2000)
                    {
                        LogCollection.Clear();
                    }
                    var log = new Log(1, DateTime.Now, sData, LogLevel.Info);
                    LogCollection.Add(log); 
                });
            };
        }
        // 初始化
        private void Initialize() 
        {
            PortNames = new ObservableCollection<string>();
            BaudRates = new ObservableCollection<int>();
            // 获取所有可用的COM端口名称
            string[] ports = SerialPort.GetPortNames();
            // 遍历并输出每个COM端口名称
            foreach (string port in ports)
            {
                PortNames.Add(port);
            }
            // 添加波特率
            BaudRates.Add(1200);
            BaudRates.Add(2400);
            BaudRates.Add(4800);
            BaudRates.Add(9600);
            BaudRates.Add(14400);
            BaudRates.Add(19200);
            BaudRates.Add(38400);
            BaudRates.Add(56000);
            BaudRates.Add(57600);
            BaudRates.Add(115200);
            BaudRates.Add(128000);
            BaudRates.Add(230400);
            BaudRates.Add(256000);
            BaudRates.Add(460800);
        }
        /// <summary>
        /// 打开串口
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        private void SerialPortConnection()
        {
            if (SerialCommunication.IsOpen)
            {
                SerialCommunication.ClosePort();
            }
            else
            {
                SerialCommunication.OpenPort();
            }
            IsSerialPortConnected = SerialCommunication.IsOpen;
        }
        /// <summary>
        /// 选择端口
        /// </summary>
        /// <param name="obj"></param>
        private void SelectPort(object obj)
        {
            SerialCommunication.PortName = (string)obj;
        }
        /// <summary>
        /// 选择波特率
        /// </summary>
        /// <param name="obj"></param>
        private void SelectBaudRate(object obj)
        {
            SerialCommunication.BaudRate = (int)obj;
        }
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="obj"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void SendData(object obj)
        {
            SerialCommunication.SendData((string)obj+Environment.NewLine);
        }
        /// <summary>
        /// 返回上一个视图
        /// </summary>
        private void BackToPreviousView()
        {
            RegionManager.RequestNavigate(RegionNames.NavigationRegion, ViewNames.SystemSettingView);
        }
    }
}
